using System;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using Server.Mobiles;
using Server.Network;

namespace Server.Mobiles
{
	public class Maintenance
	{
		public static void Configure()
		{
			EventSink.WorldSave += new WorldSaveEventHandler( OnSave );
		}

		public static void Initialize()
		{
			EventSink.Login += new LoginEventHandler( OnLogin );
			EventSink.ServerStarted += new ServerStartedEventHandler( OnStarted );
		}

		public static void OnSave( WorldSaveEventArgs e )
		{
			if ( SaveStone.TradePets != null && SaveStone.TradePets.Count > 0 )
			{
				for ( int i = 0; i < SaveStone.TradePets.Count; i++ )
				{
					TradeMobile tm = SaveStone.TradePets[i] as TradeMobile;

					// to removed deleted records
					if ( tm.m_pet == null || tm.m_pet.Deleted )
					{
						SaveStone.TradePets.RemoveAt( i-- );
					}
					else if ( tm.m_owner == null || tm.m_owner.Deleted )
					{
						Timer.DelayCall( TimeSpan.Zero, new TimerStateCallback( RemovePet_Callback ), new object[] { tm.m_pet } );
					}
					else if ( ( tm.m_vendor == null || tm.m_vendor.Deleted ) && !( tm.m_vendor is RestockableVendor ) )
					{
						tm.m_pet.ControlTarget = null;
						tm.m_pet.ControlOrder = OrderType.Stay;
						tm.m_pet.Internalize();

						tm.m_pet.SetControlMaster( null );
						tm.m_pet.SummonMaster = null;
						tm.m_pet.IsStabled = true;
						tm.m_pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy
						tm.m_owner.Stabled.Add( tm.m_pet );

						SaveStone.TradePets.RemoveAt( i-- );
					}
					else if ( ( tm.m_vendor == null || tm.m_vendor.Deleted ) && tm.m_vendor is RestockableVendor )
					{
						Timer.DelayCall( TimeSpan.Zero, new TimerStateCallback( RemovePet_Callback ), new object[] { tm.m_pet } );
						// TradePets will not be removed here, as there might not be enough time
						// They will be removed in next OnSave() cycle
//						SaveStone.TradePets.RemoveAt( i-- );
					}

				}
			}
		}

		private static void RemovePet_Callback( object state )
		{
			object[] aState = (object[]) state;

			BaseCreature pet = (BaseCreature) aState[0];

			pet.Internalize();
			pet.Delete();
		}

		private static void OnLogin( LoginEventArgs e )
		{
			Mobile from = e.Mobile;

			DisplayLastBid( from );
			TrimBidRecords( from );
		}

		private static void OnStarted()
		{
		}

		public static void TrimBidRecords( Mobile from )
		{
			if ( SaveStone.PlayerBids != null && SaveStone.PlayerBids.ContainsKey( from ) )
			{
				List<BidRecord> list = (List<BidRecord>)SaveStone.PlayerBids[from];

				for ( int i = 0; i < list.Count; i++ )
				{
					BidRecord br = (BidRecord)list[i];
					bool hit = false;

					if ( br.m_vendor == null || br.m_vendor.Deleted )
					{
						list.RemoveAt( i-- );
						hit = true;
					}
					else if ( ( DateTime.Now > br.m_expire + TimeSpan.FromDays( 6.0 ) ) && br.m_comment != "Succeeded" )
					{
						list.RemoveAt( i-- );
						hit = true;
					}
					else if ( DateTime.Now > br.m_expire )
					{
						br.m_comment = "Expired";
						hit = true;
					}

					if ( !hit )
					{
						IHardsellable hs = br.m_vendor as IHardsellable;
						bool found = false;
	
						if ( br.m_vendor != null && !br.m_vendor.Deleted && hs.BidItems != null && hs.BidItems.Count > 0 )
						{
							for ( int j = 0; j < hs.BidItems.Count; j++ )
							{
								BidByItem bbi = (BidByItem)hs.BidItems[j];
								Item item = bbi.m_itemobj as Item;
		
								if ( item.Serial == br.m_serial )
								{
									for ( int k = 0; k < bbi.m_byprice.Count; k++ )
									{
										if ( bbi.m_byprice[k].m_bider == from )
											found = true;
									}
								}
							}
						}

						if ( !found )
							list.RemoveAt( i-- );
					}
				}
			}
		}

		// TODO: to inform staff as well?
		private static void DisplayLastBid( Mobile from )
		{
			if ( SaveStone.LastBids != null && SaveStone.LastBids.ContainsKey( from ) )
			{
				BidByItem bbi = (BidByItem)SaveStone.LastBids[from];
				bool valid = true;

				if ( bbi != null && !bbi.IsExpired )
				{
					Item item = bbi.m_itemobj as Item;

					if ( item != null && !item.Deleted && item.RootParent is IHardsellable )
					{
						IHardsellable hs = item.RootParent as IHardsellable;
						Mobile vendor = item.RootParent as Mobile;

						if ( hs.BidItems != null && hs.BidItems.Count > 0 )
						{
							foreach ( BidByItem byi in hs.BidItems )
							{
								if ( byi == bbi )
								{
									TradeItem ti = VendorManager.GetTradeItem( hs, item );
									if ( ti != null )
									{
										if ( bbi.m_start > ((PlayerMobile)from).LastOnline )
											from.SendMessage( 1159, "You have new bid received." );

										from.SendMessage( 1160, "Your last bid received is from vendor {0}. Item: {1}, Start: {2}", vendor.Name, ti.Description, bbi.m_start.ToString() );
									}
									else
										valid = false;
								}
								else
									valid = false;
							}
						}
						else
							valid = false;
					}
					else
						valid = false;
				}
				else
					valid = false;

				if ( !valid )
					SaveStone.LastBids.Remove( from );
			}
		}

	}
}
